package org.light.domain;

import org.light.complexverb.AddUploadDomainField;
import org.light.complexverb.DomainFieldVerb;
import org.light.complexverb.MtmUtilMethodGenerator;
import org.light.core.GinController;
import org.light.core.PrismInterface;
import org.light.core.Verb;
import org.light.easyuilayouts.EasyUIEnumGridPagePI;
import org.light.exception.ValidateException;
//import org.light.layouts.EasyUIEnumGridPagePI;
import org.light.layouts.EasyUIGridPagePI;
import org.light.layouts.EasyUIMtmPI;
import org.light.limitedverb.CountActiveRecords;
import org.light.limitedverb.CountAllPage;
import org.light.limitedverb.CountSearchByFieldsRecords;
import org.light.limitedverb.DaoOnlyVerb;
import org.light.limitedverb.NoControllerVerb;
import org.light.utils.StringUtil;
import org.light.verb.Activate;
import org.light.verb.ActivateAll;
import org.light.verb.Add;
import org.light.verb.CheckAccess;
//import org.light.verb.CheckAccess;
import org.light.verb.Clone;
import org.light.verb.CloneAll;
import org.light.verb.Delete;
import org.light.verb.DeleteAll;
import org.light.verb.Export;
import org.light.verb.ExportPDF;
import org.light.verb.FilterExcel;
import org.light.verb.FilterPDF;
import org.light.verb.FindById;
import org.light.verb.FindByName;
import org.light.verb.FindIndexedName;
//import org.light.verb.FindIndexedName;
import org.light.verb.ListActive;
import org.light.verb.ListAll;
import org.light.verb.SearchByFields;
import org.light.verb.SearchByFieldsByPage;
import org.light.verb.SoftDelete;
import org.light.verb.SoftDeleteAll;
import org.light.verb.Toggle;
import org.light.verb.ToggleOne;
import org.light.verb.Update;
import org.light.verb.View;

public class DummyPrism extends Prism implements Comparable<Prism> {
	@Override
	public void generatePrismFiles(Boolean ignoreWarning,Boolean genUi,Boolean genController,Boolean genService,Boolean genServiceImpl,Boolean genDao,Boolean genDaoImpl) throws ValidateException {
		ValidateInfo info = this.validate(ignoreWarning);
		if (info.success(ignoreWarning) == false) {
			ValidateException e = new ValidateException(info);
			throw e;
		}
		try {
			String srcfolderPath = folderPath;
			srcfolderPath = folderPath + packagetokenToFolder(this.packageToken);

			writeToFile(srcfolderPath +packagetokenToFolder(this.domain.getDomainSuffix())  +this.getDomain().getCapFirstDomainNameWithSuffix()+ ".go",
				this.getDomain().generateClassStatementList().getContent());

			if (genDaoImpl&&this.getDaoImpl() != null) {
				writeToFile(
						srcfolderPath + packagetokenToFolder(this.domain.getDaoimplSuffix()) +  this.getDomain().getCapFirstDomainName() + "DummyDao.go",
						this.getDaoimpl().generateDaoImplString());
			}

			if (genServiceImpl&&this.getServiceImpl() != null) {
				writeToFile(srcfolderPath + packagetokenToFolder(this.domain.getServiceimplSuffix()) + this.getDomain().getCapFirstDomainName()
						+ "DummyService.go", this.getServiceImpl().generateServiceImplString());
			}

			if (genController&&this.ginController != null) {
				writeToFile(srcfolderPath +  packagetokenToFolder(this.domain.getControllerSuffix())  + this.domain.getCapFirstDomainName()
						+StringUtil.capFirst(this.domain.getControllerNamingSuffix())+".go", this.ginController.generateControllerString());
			}

			if (genUi) {
				for (PrismInterface page : this.pages) {
					page.generatePIFiles(folderPath);
				}

				for (ManyToMany mtm : this.manyToManies) {
					EasyUIMtmPI mpage = mtm.getEuPI();
					mpage.setTechnicalStack(this.technicalStack);
					mpage.setTitles(this.getTitle(), this.getSubTitle(), this.getFooter());
					mpage.setNav(this.getNav());
					mpage.generatePIFiles(folderPath);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void generatePrismFromDomain(Boolean ignoreWarning) throws ValidateException, Exception {
		if (this.domain != null) {
			if (this.getPackageToken() != null) {
				this.domain.setPackageToken(packageToken);
			}

			this.daoimpl = new DummyDaoImpl();
			this.daoimpl.setPackageToken(this.domain.getPackageToken());
			this.daoimpl.setDomain(this.domain);
			
			this.dummydaoimpl = new DummyDaoImpl();
			this.dummydaoimpl.setPackageToken(this.domain.getPackageToken());
			this.dummydaoimpl.setDomain(this.domain);

			this.serviceimpl = new ServiceImpl(this.domain);
			this.serviceimpl.setPackageToken(this.domain.getPackageToken());
			this.serviceimpl.setDomain(this.domain);
			Method existsInArr = MtmUtilMethodGenerator.generateExistsInArrMethod(this.domain);
			this.serviceimpl.addMethod(existsInArr);
			
			this.dummyserviceimpl = new DummyServiceImpl(this.domain);
			this.dummyserviceimpl.setPackageToken(this.domain.getPackageToken());
			this.dummyserviceimpl.setDomain(this.domain);
			this.dummyserviceimpl.addMethod(existsInArr);			

			Verb listAll = new ListAll(this.domain);			
			Verb update = this.domain.hasDomainId() ?new Update(this.domain):null;
			Verb delete = this.domain.hasDomainId() ?new Delete(this.domain):null;
			Verb add = this.domain.hasDomainId() ?new Add(this.domain):null;
			Verb view = this.domain.hasDomainId() ?new View(this.domain):null;
			Verb softdelete = this.domain.hasDomainId() && this.domain.hasActiveField() ?new SoftDelete(this.domain):null;
			Verb findbyid = this.domain.hasDomainId() ? new FindById(this.domain):null;
			Verb findbyname = this.domain.hasDomainName() ? new FindByName(this.domain):null;
			//Verb searchbyname = this.domain.hasDomainName()?new SearchByName(this.domain):null;
			Verb listactive = this.domain.hasActiveField()?new ListActive(this.domain):null;
			Verb deleteAll = this.domain.hasDomainId() ?new DeleteAll(this.domain):null;
			Verb softDeleteAll = this.domain.hasDomainId() && this.domain.hasActiveField() ?new SoftDeleteAll(this.domain):null;
			Verb toggle = this.domain.hasDomainId() && this.domain.hasActiveField() ?new Toggle(this.domain):null;
			Verb toggleOne = this.domain.hasDomainId() && this.domain.hasActiveField() ?new ToggleOne(this.domain):null;
			Verb searchByFieldsByPage = new SearchByFieldsByPage(this.domain);
			Verb activate = this.domain.hasDomainId() && this.domain.hasActiveField() ?new Activate(this.domain):null;
			Verb activateAll = this.domain.hasDomainId() && this.domain.hasActiveField() ?new ActivateAll(this.domain):null;
			Verb export = new Export(this.domain);
			Verb exportPDF = new ExportPDF(this.domain);
			Verb searchByFields = new SearchByFields(this.domain);
			Verb filterExcel = new FilterExcel(this.domain);
			Verb filterPDF = new FilterPDF(this.domain);
			Verb clone	= this.domain.hasDomainId() ?new Clone(this.domain):null;
			Verb findIndexedName = this.domain.hasDomainId() ?new FindIndexedName(this.domain):null;
			Verb cloneAll = this.domain.hasDomainId()  ?new CloneAll(this.domain):null;
			Verb checkAcces = new CheckAccess(this.domain);
			
			CountAllPage countAllPage = new CountAllPage(this.domain);
			CountSearchByFieldsRecords countSearch = new CountSearchByFieldsRecords(this.domain);
			CountActiveRecords countActiveRecords = this.domain.hasDomainId() && this.domain.hasActiveField() ? new CountActiveRecords(this.domain):null;

			for (Field f:this.domain.getPlainFields()) {
				if (f.getFieldType().equalsIgnoreCase("image")) {
					domianFieldVerbs.add(new AddUploadDomainField(this.domain,f));
				}
			}
			this.addVerb(listAll);
			this.addVerb(update);
			this.addVerb(delete);
			this.addVerb(add);
			this.addVerb(view);
			this.addVerb(softdelete);
			this.addVerb(findbyid);
			this.addVerb(findbyname);
			//this.addVerb(searchbyname);
			this.addVerb(listactive);
			this.addVerb(deleteAll);
			this.addVerb(softDeleteAll);
			this.addVerb(toggle);
			this.addVerb(toggleOne);
			this.addVerb(searchByFieldsByPage);
			this.addVerb(activate);
			this.addVerb(activateAll);
			this.addVerb(export);
			this.addVerb(exportPDF);
			this.addVerb(searchByFields);
			this.addVerb(filterExcel);
			this.addVerb(filterPDF);
			this.addVerb(clone);
			this.addVerb(findIndexedName);
			this.addVerb(cloneAll);
			this.addVerb(checkAcces);

			if (countAllPage !=null) this.noControllerVerbs.add(countAllPage);
			if (countSearch !=null) this.noControllerVerbs.add(countSearch);
			if (countActiveRecords !=null) this.noControllerVerbs.add(countActiveRecords);
			this.ginController = new GinController(this.domain);
			this.ginController.setPackageToken(this.packageToken);

			for (Verb v : this.verbs) {
				v.setDomain(domain);
				v.setDbType(domain.getDbType());
				serviceimpl.addMethod(v.generateServiceImplMethod());
				dummyserviceimpl.addMethod(v.generateDummyServiceImplMethod());
				daoimpl.addMethod(v.generateDummyDaoImplMethod());
				dummydaoimpl.addMethod(v.generateDummyDaoImplMethod());
				ginController.addMethod(v.generateControllerMethod());
			}

			for (NoControllerVerb nVerb : this.noControllerVerbs) {				
				nVerb.setDomain(domain);
				if (! (nVerb instanceof CountActiveRecords)) {
					serviceimpl.addMethod(nVerb.generateServiceImplMethod());
					dummyserviceimpl.addMethod(nVerb.generateDummyServiceImplMethod());
				}
				daoimpl.addMethod(nVerb.generateDummyDaoImplMethod());
				dummydaoimpl.addMethod(nVerb.generateDummyDaoImplMethod());
			}

			for (DaoOnlyVerb oVerb : this.daoOnlyVerbs) {
				oVerb.setDomain(domain);
				daoimpl.addMethod(oVerb.generateDummyDaoImplMethod());
				dummydaoimpl.addMethod(oVerb.generateDummyDaoImplMethod());
			}
			
			for (DomainFieldVerb dfv:domianFieldVerbs) {
				this.ginController.addMethod(dfv.generateControllerMethod());
			}

			EasyUIGridPagePI easyui = new EasyUIGridPagePI(this.domain);
			easyui.setTitles(this.getTitle(),this.getSubTitle(),this.getFooter());
			easyui.setDomain(this.domain);
			easyui.setTechnicalStack(this.technicalStack);
			this.addPage(easyui);

			if (this.domain.manyToManies != null && this.domain.manyToManies.size() > 0) {
				for (ManyToMany mtm : this.domain.manyToManies) {
					String slaveName = mtm.getManyToManySalveName();
					String masterName = this.domain.getStandardName();
					if (setContainsDomain(this.projectDomains, masterName)
							&& setContainsDomain(this.projectDomains, slaveName)) {
						Domain tempo = lookupDomainInSet(this.projectDomains, slaveName);
						Domain myslave = tempo==null?null:(Domain)tempo.deepClone();
						if (myslave == null) continue;
						if (!StringUtil.isBlank(mtm.getSlaveAlias())){
							myslave.setAlias(mtm.getSlaveAlias());
							myslave.setAliasLabel(mtm.getSlaveAliasLabel());
						}
						ManyToMany mymtm = new ManyToMany(lookupDomainInSet(this.projectDomains, masterName),
								myslave,mtm.getMasterValue(),mtm.getValues());	
						mymtm.setSlaveAlias(myslave.getAlias());
						mymtm.setSlaveAliasLabel(mtm.getSlaveAliasLabel());
						mymtm.setValues(mtm.getValues());
						this.manyToManies.add(mymtm);
						logger.debug("JerryDebug:"+mymtm+":Master:"+masterName+":"+myslave.getAlias()+"");
					} else {
						ValidateInfo validateInfo = new ValidateInfo();
						validateInfo.addCompileError("棱柱" + this.getText() + "多对多设置有误。");
						ValidateException em = new ValidateException(validateInfo);
						throw em;
					}
				}
			}
			for (ManyToMany mtm : this.manyToManies) {
				mtm.setTitle(this.title);
				mtm.setSubTitle(this.subTitle);
				mtm.setFooter(this.footer);
				mtm.setCrossOrigin(this.crossOrigin);
				
				this.serviceimpl.addMethod(mtm.getAssign().generateServiceImplMethod());
				this.daoimpl.addMethod(mtm.getAssign().generateDummyDaoImplMethod());
				this.dummydaoimpl.addMethod(mtm.getAssign().generateDummyDaoImplMethod());
				this.ginController.addMethod(mtm.getAssign().generateControllerMethod());

				this.service.addMethod(mtm.getRevoke().generateServiceMethodDefinition());
				this.daoimpl.addMethod(mtm.getRevoke().generateDummyDaoImplMethod());
				this.dummydaoimpl.addMethod(mtm.getRevoke().generateDummyDaoImplMethod());
				this.ginController.addMethod(mtm.getRevoke().generateControllerMethod());

				this.serviceimpl.addMethod(mtm.getListMyActive().generateServiceImplMethod());
				this.daoimpl.addMethod(mtm.getListMyActive().generateDummyDaoImplMethod());
				this.dummydaoimpl.addMethod(mtm.getListMyActive().generateDummyDaoImplMethod());
				this.ginController.addMethod(mtm.getListMyActive().generateControllerMethod());

				this.serviceimpl.addMethod(mtm.getListMyAvailableActive().generateServiceImplMethod());
				this.daoimpl.addMethod(mtm.getListMyAvailableActive().generateDummyDaoImplMethod());
				this.dummydaoimpl.addMethod(mtm.getListMyAvailableActive().generateDummyDaoImplMethod());
				this.ginController.addMethod(mtm.getListMyAvailableActive().generateControllerMethod());		
			}
		}
	}
	
	public void generateEnumPrismFromEnum(Boolean ignoreWarning) throws ValidateException, Exception {
		if (this.domain != null && this.domain instanceof Enum) {
			if (this.getPackageToken() != null) {
				this.domain.setPackageToken(packageToken);
			}

			this.daoimpl = new DummyDaoImpl();
			this.daoimpl.setPackageToken(this.domain.getPackageToken());
			this.daoimpl.setDomain(this.domain);
			
			this.dummydaoimpl = new DummyDaoImpl();
			this.dummydaoimpl.setPackageToken(this.domain.getPackageToken());
			this.dummydaoimpl.setDomain(this.domain);

			this.serviceimpl = new ServiceImpl(this.domain);
			this.serviceimpl.setPackageToken(this.domain.getPackageToken());
			this.serviceimpl.setDomain(this.domain);			
			Method existsInArr = MtmUtilMethodGenerator.generateExistsInArrMethod(this.domain);
			this.serviceimpl.addMethod(existsInArr);
			
			this.dummyserviceimpl = new DummyServiceImpl(this.domain);
			this.dummyserviceimpl.setPackageToken(this.domain.getPackageToken());
			this.dummyserviceimpl.setDomain(this.domain);
			this.dummyserviceimpl.addMethod(existsInArr);			

			Verb view = this.domain.hasDomainId() ?new View(this.domain):null;
			Verb listAll = new ListAll(this.domain);			
			Verb findbyid = this.domain.hasDomainId() ? new FindById(this.domain):null;
			Verb findbyname = this.domain.hasDomainName() ? new FindByName(this.domain):null;
			//Verb searchbyname = this.domain.hasDomainName()?new SearchByName(this.domain):null;
			Verb listactive = this.domain.hasActiveField()?new ListActive(this.domain):null;
			Verb searchByFieldsByPage = new SearchByFieldsByPage(this.domain);
			Verb export = new Export(this.domain);
			Verb exportPDF = new ExportPDF(this.domain);
			Verb searchByFields = new SearchByFields(this.domain);
			Verb filterExcel = new FilterExcel(this.domain);
			Verb filterPDF = new FilterPDF(this.domain);
			Verb checkAcces = new CheckAccess(this.domain);
			
			CountAllPage countAllPage = new CountAllPage(this.domain);
			CountSearchByFieldsRecords countSearch = new CountSearchByFieldsRecords(this.domain);
			CountActiveRecords countActiveRecords = this.domain.hasDomainId() && this.domain.hasActiveField() ? new CountActiveRecords(this.domain):null;

			for (Field f:this.domain.getPlainFields()) {
				if (f.getFieldType().equalsIgnoreCase("image")) {
					domianFieldVerbs.add(new AddUploadDomainField(this.domain,f));
				}
			}
			this.addVerb(view);
			this.addVerb(listAll);
			this.addVerb(findbyid);
			this.addVerb(findbyname);
			//this.addVerb(searchbyname);
			this.addVerb(listactive);
			this.addVerb(searchByFieldsByPage);
			this.addVerb(export);
			this.addVerb(exportPDF);
			this.addVerb(searchByFields);
			this.addVerb(filterExcel);
			this.addVerb(filterPDF);
			this.addVerb(checkAcces);

			if (countAllPage !=null) this.noControllerVerbs.add(countAllPage);
			if (countSearch !=null) this.noControllerVerbs.add(countSearch);
			if (countActiveRecords !=null) this.noControllerVerbs.add(countActiveRecords);
			this.ginController = new GinController(this.domain);
			this.ginController.setPackageToken(this.packageToken);

			for (Verb v : this.verbs) {
				v.setDomain(domain);
				v.setDbType(domain.getDbType());
				serviceimpl.addMethod(v.generateServiceImplMethod());
				dummyserviceimpl.addMethod(v.generateDummyServiceImplMethod());
				daoimpl.addMethod(v.generateDummyDaoImplMethod());
				dummydaoimpl.addMethod(v.generateDummyDaoImplMethod());
				ginController.addMethod(v.generateControllerMethod());
			}

			for (NoControllerVerb nVerb : this.noControllerVerbs) {				
				nVerb.setDomain(domain);
				if (! (nVerb instanceof CountActiveRecords)) {
					serviceimpl.addMethod(nVerb.generateServiceImplMethod());
					dummyserviceimpl.addMethod(nVerb.generateDummyServiceImplMethod());
				}
				daoimpl.addMethod(nVerb.generateDummyDaoImplMethod());
				dummydaoimpl.addMethod(nVerb.generateDummyDaoImplMethod());
			}

			for (DaoOnlyVerb oVerb : this.daoOnlyVerbs) {
				oVerb.setDomain(domain);
				daoimpl.addMethod(oVerb.generateDummyDaoImplMethod());
				dummydaoimpl.addMethod(oVerb.generateDummyDaoImplMethod());
			}
			
			for (DomainFieldVerb dfv:domianFieldVerbs) {
				this.ginController.addMethod(dfv.generateControllerMethod());
			}

			EasyUIEnumGridPagePI easyui = new EasyUIEnumGridPagePI(this.domain);
			easyui.setTitles(this.getTitle(),this.getSubTitle(),this.getFooter());
			easyui.setDomain(this.domain);
			easyui.setTechnicalStack(this.technicalStack);
			this.addPage(easyui);

			if (this.domain.manyToManies != null && this.domain.manyToManies.size() > 0) {
				for (ManyToMany mtm : this.domain.manyToManies) {
					String slaveName = mtm.getManyToManySalveName();
					String masterName = this.domain.getStandardName();
					if (setContainsDomain(this.projectDomains, masterName)
							&& setContainsDomain(this.projectDomains, slaveName)) {
						Domain tempo = lookupDomainInSet(this.projectDomains, slaveName);
						Domain myslave = tempo==null?null:(Domain)tempo.deepClone();
						if (myslave == null) continue;
						if (!StringUtil.isBlank(mtm.getSlaveAlias())){
							myslave.setAlias(mtm.getSlaveAlias());
							myslave.setAliasLabel(mtm.getSlaveAliasLabel());
						}
						ManyToMany mymtm = new ManyToMany(lookupDomainInSet(this.projectDomains, masterName),
								myslave,mtm.getMasterValue(),mtm.getValues());	
						mymtm.setSlaveAlias(myslave.getAlias());
						mymtm.setSlaveAliasLabel(mtm.getSlaveAliasLabel());
						mymtm.setValues(mtm.getValues());
						this.manyToManies.add(mymtm);
						logger.debug("JerryDebug:"+mymtm+":Master:"+masterName+":"+myslave.getAlias()+"");
					} else {
						ValidateInfo validateInfo = new ValidateInfo();
						validateInfo.addCompileError("棱柱" + this.getText() + "多对多设置有误。");
						ValidateException em = new ValidateException(validateInfo);
						throw em;
					}
				}
			}
			for (ManyToMany mtm : this.manyToManies) {
				mtm.setTitle(this.title);
				mtm.setSubTitle(this.subTitle);
				mtm.setFooter(this.footer);
				mtm.setCrossOrigin(this.crossOrigin);
				this.serviceimpl.addMethod(mtm.getAssign().generateServiceImplMethod());
				this.daoimpl.addMethod(mtm.getAssign().generateDaoImplMethod());
				this.dummydaoimpl.addMethod(mtm.getAssign().generateDummyDaoImplMethod());
				this.ginController.addMethod(mtm.getAssign().generateControllerMethod());

				this.serviceimpl.addMethod(mtm.getRevoke().generateServiceImplMethod());
				this.daoimpl.addMethod(mtm.getRevoke().generateDaoImplMethod());
				this.dummydaoimpl.addMethod(mtm.getAssign().generateDummyDaoImplMethod());
				this.ginController.addMethod(mtm.getRevoke().generateControllerMethod());

				this.serviceimpl.addMethod(mtm.getListMyActive().generateServiceImplMethod());
				this.daoimpl.addMethod(mtm.getListMyActive().generateDaoImplMethod());
				this.dummydaoimpl.addMethod(mtm.getListMyActive().generateDummyDaoImplMethod());
				this.ginController.addMethod(mtm.getListMyActive().generateControllerMethod());

				this.serviceimpl.addMethod(mtm.getListMyAvailableActive().generateServiceImplMethod());
				this.daoimpl.addMethod(mtm.getListMyAvailableActive().generateDaoImplMethod());
				this.dummydaoimpl.addMethod(mtm.getListMyAvailableActive().generateDummyDaoImplMethod());
				this.ginController.addMethod(mtm.getListMyAvailableActive().generateControllerMethod());
			}
		}
	}

	@Override
	public int compareTo(Prism o) {
		String myName = this.getStandardName();
		String otherName = o.getStandardName();
		if (StringUtil.isBlank(myName)) myName = "";
		if (StringUtil.isBlank(otherName)) otherName = "";
		return myName.compareTo(otherName);
	}

	@Override
	public boolean equals(Object o) {
		return (this.compareTo((Prism) o) == 0);
	}

}
